﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using FarseerPhysics.Dynamics;
using FarseerPhysics.Collision.Shapes;
using LensflareGameFramework;
using Util;
using FarseerPhysics.Dynamics.Contacts;
using Microsoft.Xna.Framework.Graphics;

namespace LensflareAIContest {
    public class Projectile : GameEntity {
        Body body;
        CircleShape shape;

        public float TimeToLive { get; protected set; }
        public Spaceship Owner { get; protected set; }

        public static Texture2D Texture { get; set; }

        public Projectile(LensflareAIContestGame game, Vector2 position, Vector2 direction, Spaceship owner) : base(game) {
            TimeToLive = game.Rules.Projectile.LifeSpan;
            Owner = owner;

            body = new Body(game.World);
            body.BodyType = BodyType.Dynamic;
            body.SleepingAllowed = false;
            body.LinearDamping = 0;
            body.AngularDamping = 0;

            direction.Normalize();
            float physicsSpaceScale = Game.Rules.World.PhysicsSpaceScale;
            float rotation = (float)Math.Atan2(direction.Y, direction.X);
            body.SetTransform(position * physicsSpaceScale, rotation);
            body.ApplyLinearImpulse(owner.Velocity + direction * game.Rules.Projectile.VelocityInitial * physicsSpaceScale);

            shape = new CircleShape(game.Rules.Projectile.Radius * physicsSpaceScale, 1.0f);

            Fixture fixture = new Fixture(body, shape);
            fixture.CollisionGroup = (short)CollisionGroup.Projectile;
            fixture.OnCollision += OnCollision;
        }

        protected override void Dispose() {
            body.UserData = null;
            body.Dispose();
            base.Dispose();
        }

        public Vector2 Position {
            get { return body.Position / Game.Rules.World.PhysicsSpaceScale; }
        }

        public Vector2 Velocity {
            get { return body.LinearVelocity; }
        }

        public bool OnCollision(Fixture f1, Fixture f2, Contact contact) {
            Entity.Remove(this);

            Object userData = f2.Body.UserData;

            if(userData != null) {
                if (userData is Spaceship) {
                    Spaceship hitEntity = (Spaceship)userData;
                    if (hitEntity.TeamIndex != Owner.TeamIndex) {
                        hitEntity.ApplyDamage(Game.Rules.Projectile.DamageCausedOnHit);
                    }
                } else if (userData is Heart) {
                    Heart hitEntity = (Heart)userData;
                    if (hitEntity.TeamIndex != Owner.TeamIndex) {
                        hitEntity.ApplyDamage(Game.Rules.Projectile.DamageCausedOnHit);
                    }
                }
            }
            return true;
        }

        public override void Update(GameTime gameTime) {
            float elapsedSeconds = (float)gameTime.ElapsedGameTime.TotalSeconds;

            TimeToLive -= elapsedSeconds;
            if (TimeToLive <= 0.0f) {
                Entity.Remove(this);
            }
        }

        public override void Draw() {
            if (Game.Camera.OverlapsWorldShape(shape, body, Game.Rules.World.PhysicsSpaceScale)) {
                Vector2 screenPosition = Game.Camera.Project(Position);
                float zoomedRadius = Game.Rules.Projectile.Radius * Game.Camera.Zoom;

                /*
                Primitive2.DrawCircle(Game.SpriteBatch, screenPosition, zoomedRadius, c1, true, Game.LayerManager.Depth((int)MainLayer.DynamicEntity));
                Primitive2.DrawCircle(Game.SpriteBatch, screenPosition, zoomedRadius - 1, c2, false, Game.LayerManager.Depth((int)MainLayer.DynamicEntity));
                //Primitive2.DrawCircle(Game.SpriteBatch, screenPosition, zoomedRadius - 2, c1, false, Game.LayerManager.Depth((int)MainLayer.DynamicEntity));
                */

                float layerDepth = Game.LayerManager.Depth((int)MainLayer.DynamicEntity);
                float textureZoom = Game.Rules.Projectile.Radius * 2.0f / Texture.Width;
                Game.SpriteBatch.Draw(Texture, screenPosition, null, Game.PlayerColors[Owner.TeamIndex], 0, Texture.GetCenter(), Game.Camera.Zoom * textureZoom, SpriteEffects.None, layerDepth);
            }
        }
    }
}
